package com.geek688.auxiliarytool.util;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class FileUtil {
	
	
	/**
	 * 扫描当前目录下的文件
	 * @param dir
	 * @return
	 */
	public static List<File> getFileList(String dir,String suffix) throws IOException {
		List<File> filelist = new ArrayList<File>();
		Files.walkFileTree(Paths.get(dir), new FileVisitor<Path>() {
			@Override
			public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
				return FileVisitResult.CONTINUE;
			}
			@Override
			public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
				return FileVisitResult.CONTINUE;
			}
			@Override
			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
				File data = file.toFile();
				if (data != null && data.getName().endsWith(suffix)) {
					filelist.add(data);
				}
				return FileVisitResult.CONTINUE;
			}
			@Override
			public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
				return FileVisitResult.CONTINUE;
			}
		});
		return filelist;
	}
	
	/**
	 * 判断该文件是否已存在，存在则序号加1
	 * @author hanjiefei
	 * @date 2019年3月20日
	 * @param path
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	public static File checkFile(String path,String filename) throws IOException{
		File file = new File(path+filename+".xls");
		if (!file.exists()) {
			file.createNewFile();
		}else{
			String num = "0";
			filename = file.getName();
			if (filename.lastIndexOf(".") != -1) {
				filename = filename.substring(0, filename.lastIndexOf("."));
			}
			if (filename.indexOf("(") != -1) {
				num = filename.substring(filename.indexOf("(")+1, filename.indexOf(")"));
				filename = filename.substring(0, filename.indexOf("("));
			}
			file = checkFile(path,filename+"("+(Integer.valueOf(num)+1)+")");
		}
		return file;
	}
	/**
	 * 获取文件文本内容
	 * @param fileUrl 文件路径
	 * @return
	 * @throws Exception 
	 */
	public static String getFileText(String fileUrl) {
		fileUrl = removeBackSlant(fileUrl);	//去除url结尾的所以反斜杠
		if(fileUrl==null || fileUrl.length()==0){
			String message = "文件路径为空!!";
			throw new RuntimeException(message);
		}
		
		File file = new File(fileUrl);
		
		String fileContentString = null;
		if(!file.isFile()){
			String msg = "不是一个标准的文件";
			log.error(msg);
			return null;
		}
		
		FileInputStream is = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		try {
			String charset = CpdetectorUtils.getFileOrIOEncode(file.getAbsolutePath(), CpdetectorUtils.FILE_ENCODE_TYPE);
//			log.debug("文件编码: "+charset);
			is = new FileInputStream(file);
			
			byte[] buffers = new byte[512];
			int count = 0;
			while((count = is.read(buffers))>0){
				bos.write(buffers, 0, count);
			}
			fileContentString = new String(bos.toByteArray(),charset);
			
		} catch (FileNotFoundException e) {
			log.error("",e);
		} catch (IOException e) {
			log.error("",e);
		} catch (Exception e) {
			log.error("",e);
		} finally {
			if(is != null){
				try {
					is.close();
					is = null;
				} catch (IOException e) {
					log.error("",e);
				}
			}
			if(bos != null){
				try {
					bos.close();
					bos = null;
				} catch (IOException e) {
					log.error("",e);
				}
			}
		}
		
		return fileContentString;
	}
	
	/**
	 * 创建文本文件
	 * @param text
	 * @param catalogUrl
	 */
	public static void text2File(String text,String catalogUrl){
		catalogUrl = removeBackSlant(catalogUrl);	//去除url结尾的所以反斜杠
		if(catalogUrl==null || catalogUrl.length()==0){
			String message = "文件路径为空!!";
			throw new RuntimeException(message);
		}
		File file = new File(catalogUrl);
		if(!file.exists()){
			try {
				file.createNewFile();
				if(!file.exists()){
					String msg = "不是一个标准的文件";
					log.error(msg);
					throw new RuntimeException(msg);
				}
			} catch (IOException e) {
				String msg = "创建文件失败!";
				log.error(msg,e);
			}
		}
		OutputStreamWriter writer = null;
		BufferedWriter out = null;
		try {
			String charsetName = CpdetectorUtils.getFileOrIOEncode(file.getPath(), CpdetectorUtils.FILE_ENCODE_TYPE);
			writer = new OutputStreamWriter(new FileOutputStream(file), charsetName);
			out = new BufferedWriter(writer);
			out.write(text, 0, text.length());
			out.close();
		} catch (FileNotFoundException e) {
			log.error("",e);
		} catch (IOException e) {
			log.error("",e);
		} finally {
			if(writer != null){
				try {
					writer.close();
					writer = null;
				} catch (IOException e) {
					log.error("",e);
				}
			}
			if(out != null){
				try {
					out.close();
					out = null;
				} catch (IOException e) {
					log.error("",e);
				}
			}
		}
	}
	
	/**
	 * 对文件文本内容选择替换
	 * @param fileUrl 文件路径
	 * @param oldChar 要替换的内容数组
	 * @param newChar 替换的新内容数组
	 */
	public static void replaceFileText(String fileUrl, String[] oldChars, String[] newChars) {
		fileUrl = removeBackSlant(fileUrl);	//去除url结尾的所以反斜杠
		if(fileUrl==null || fileUrl.length()==0){
			String message = "文件路径为空!!";
			throw new RuntimeException(message);
		}
		if(oldChars==null){
			String message = "要替换的内容数组为null";
			throw new RuntimeException(message);
		}
		if(newChars==null){
			String message = "替换的新内容数组为null";
			throw new RuntimeException(message);
		}
		if(oldChars.length!=newChars.length){
			String message = "旧内容数组与新内容数组长度不一致";
			throw new RuntimeException(message);
		}
		String fileContentString = getFileText(fileUrl);	//得到文件文本内容
		fileContentString = fileContentString.replaceAll("(\r\n)|(\n)", "\\\\r\\\\n");
//		fileContentString = fileContentString.replaceAll("(\")", """);
//		System.out.println(fileContentString);
		for(int i=0;i<oldChars.length;i++){
			String oldChar = oldChars[i];
			String newChar = newChars[i];
			fileContentString = fileContentString.replace(oldChar, newChar);
		}
//		System.out.println(fileContentString);
		fileContentString = fileContentString.replaceAll("(\\\\r\\\\n)|(\\\\n)", "\r\n");
//		System.out.println(fileContentString);
		text2File(fileContentString,fileUrl);
		
	}
	
	/**
	 * 提取文本文件内容并可替换内容后到新文件
	 * @param fileUrl
	 * @param catalogUrl
	 * @param oldChars
	 * @param newChars
	 */
	public static void fileText2NewFile(String fileUrl,String catalogUrl , String[] oldChars, String[] newChars){
		fileUrl   =  removeBackSlant(fileUrl);	//去除url结尾的所以反斜杠
		catalogUrl = removeBackSlant(catalogUrl);
		if(fileUrl==null || fileUrl.length()==0){
			String message = "文件路径为空!!";
			throw new RuntimeException(message);
		}
		if(catalogUrl==null || catalogUrl.length()==0){
			String message = "文件路径为空!!";
			throw new RuntimeException(message);
		}
		if(oldChars==null){
			String message = "要替换的内容数组为null";
			throw new RuntimeException(message);
		}
		if(newChars==null){
			String message = "替换的新内容数组为null";
			throw new RuntimeException(message);
		}
		if(oldChars.length!=newChars.length){
			String message = "旧内容数组与新内容数组长度不一致";
			throw new RuntimeException(message);
		}
		String fileContentString = getFileText(fileUrl);	//得到文件文本内容
		for(int i=0;i<oldChars.length;i++){
			String oldChar = oldChars[i];
			String newChar = newChars[i];
			fileContentString = fileContentString.replace(oldChar, newChar);
		}
		text2File(fileContentString,catalogUrl);
	}
	
	/**
	 * 去除字符串后的反斜杠"\"
	 * 会将正斜杠换为两个反斜杠,并且去除结尾的反斜杠"\"
	 * @param url
	 * @return
	 */
	public static String removeBackSlant(String url){
		String _url = url.replaceAll("/", "\\");
		boolean endsWith = _url.endsWith("\\");
		if(endsWith){
			int lastIndexOf = _url.lastIndexOf("\\");
			String _new = _url.substring(0, lastIndexOf);
			return removeBackSlant(_new);
		} else {
			return _url;
		}
	}
}
